#include <fstream>
#include "WorldDescriptor.h"

using namespace game_engine::data_format;

///////////////////////////////////////////////////////////////////////////////
// Constructors and Destructors
///////////////////////////////////////////////////////////////////////////////

WorldDescriptor::WorldDescriptor(void)
    : filename(), worldWidth(0), worldHeight(0), tileWidth(0), tileHeight(0)
{
}

WorldDescriptor::WorldDescriptor(const string &file)
    : filename(file), worldWidth(0), worldHeight(0), tileWidth(0), 
    tileHeight(0)
{
}

WorldDescriptor::~WorldDescriptor(void)
{
}

///////////////////////////////////////////////////////////////////////////////
// Other public methods
///////////////////////////////////////////////////////////////////////////////

void WorldDescriptor::parse(void)
{
    // Read all contents from the file
    ifstream fin(filename.c_str(), ifstream::in);
    if (!fin || !fin.good() || fin.eof())
    {
        // throw exception
        string err("error in input file");
        throw runtime_error(err);
    }

    // Read level dimensions (in tiles)
    string content;
    // Skip information line
    getline(fin, content);
    getline(fin, content, DIM_SEPARATOR);
    worldWidth = atoi(content.c_str());
    getline(fin, content);
    worldHeight = atoi(content.c_str());
    
    // Read tile's dimensions in pixels
    // Skip information line
    getline(fin, content);
    getline(fin, content, DIM_SEPARATOR);
    tileWidth = atoi(content.c_str());
    getline(fin, content);
    tileHeight = atoi(content.c_str());

    // Read tile's texture information
    // Skip information line
    getline(fin, content);
    for (INT32 y=0; y<worldHeight; y++)
    {
        INT32 x = 0;
        vector<INT32> row;
        for (x=0; x<(worldWidth-1); x++)
        {
            getline(fin, content, TILE_SEPARATOR);
            row.push_back(atoi(content.c_str()));
        }
        // Read last tile in row
        getline(fin, content);
        row.push_back(atoi(content.c_str()));

        textureId.push_back(row);
    }
    
    // Read tile's physics information
    // Skip information line
    getline(fin, content);
    for (INT32 y=0; y<worldHeight; y++)
    {
        INT32 x = 0;
        vector<INT32> row;
        for (x=0; x<(worldWidth-1); x++)
        {
            getline(fin, content, PHYS_SEPARATOR);
            row.push_back(atoi(content.c_str()));
        }
        // Read last tile in row
        getline(fin, content);
        row.push_back(atoi(content.c_str()));

        physics.push_back(row);
    }

    // Close level file
    fin.close();
}

///////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////

const string& WorldDescriptor::getFilename(void) const
{
    return filename;
}

const INT32 WorldDescriptor::getWorldWidth(void) const
{
    return worldWidth;
}

const INT32 WorldDescriptor::getWorldHeight(void) const
{
    return worldHeight;
}

const INT32 WorldDescriptor::getTileWidth(void) const
{
    return tileWidth;
}

const INT32 WorldDescriptor::getTileHeight(void) const
{
    return tileHeight;
}

const INT32 WorldDescriptor::getTextureId(const UINT32 x, const UINT32 y) const
{
    // Attention: lecture is done in transposed matrix
    return textureId[y][x];
}

const INT32 WorldDescriptor::getPhysicsInfo(const UINT32 x, const UINT32 y) 
    const
{
    // Attention: lecture is done in transposed matrix
    return physics[y][x];
}
